#include "BreakPointService.h"
#include <iostream>
#include "BreakPointFile.h"
#include "BreakPointDecorator.h"

#include "BreakPointState.h"

BreakPointService::BreakPointService()
: state(new BreakPointState)
, breakPoint(new BreakPointDecorator(new BreakPointFile("./seqNo.bin")))
{
}
BreakPointService::~BreakPointService()
{
    if(breakPoint != nullptr){
        delete breakPoint;
        breakPoint = nullptr;
    }
    if(state != nullptr){
        delete state;
        state = nullptr;
    }
}


int BreakPointService::start(){
    std::cout << "BreakPointService::start " << std::endl;

    if(0 == state->toInited()){
        //first loadFromFile, then set to mem
        std::cout << "BreakPointService::loadFromFile, breakPoint:" 
            << breakPoint->get() << std::endl;
        return 0;
    }

    std::cout << "switch to Inited status failed" << std::endl;
    state->log(std::cout) << std::endl;
    return -1;
}

int BreakPointService::stop(){
    std::cout << "BreakPointService::stop to: " << breakPoint->get() << std::endl;
    if(0 == state->toEnd()){
        std::cout << "BreakPointService::saveToFile " << std::endl;
        breakPoint->set(breakPoint->get());//save the mem seqNo to file
        return 0;
    }
    else{
        std::cout << "status check error: END status already" << std::endl;
        state->log(std::cout);
        return -1;
    }
}

int BreakPointService::connected(){
    std::cout << "BreakPointService::connected " << std::endl;
    if(0 == state->toConnected()){
        return sendMessage("login-req");
    }
    else{
        std::cout << "current status error:" << std::endl;
        state->log(std::cout);
        return -1;
    }
}
int BreakPointService::disconnected(){
    if(0 == state->toDisconnected()){
        std::cout << "BreakPointService::disconnected " << std::endl;
        return 0;
    }
    else{
        std::cout << "current status error:" << std::endl;
        state->log(std::cout);
        return -1;
    }
}


int BreakPointService::receivedLoginResp(const char * msg){
    std::cout << "BreakPointService::receive :[" << msg << "]" 
        << "\n\tswitch to [login] status if response ok" 
        << std::endl;

    if(0 == state->toLogined()){
        return 0;
    } 
    else{
        std::cout << "status error: need connected status" << std::endl;
        state->log(std::cout);
        return -1;
    }
}

int BreakPointService::receivedBreakPointResp(const char * msg){
    std::cout << "BreakPointService::receive :[" << msg << "]" << std::endl;
    if(state->isLogined()){
        return 0;
    }
    std::cout << "Error: need LOGINED status " << std::endl;
    return -1;
}

int BreakPointService::receivedNormalResp(const char * msg){
    std::cout << "BreakPointService::receive :[" << msg << "]" << std::endl;
    if(state->isLogined()){
        breakPoint->add(1); //fake action
        return 0;
    }
    else{
        std::cout << "Error: need LOGINED status " << std::endl;
        return -1;
    }
}

int BreakPointService::sendMessage(const char * msg){
    if(state->isLogined() || state->isConnected()){
        std::cout << "BreakPointService::send : [" << msg << "] " << std::endl;
        state->log(std::cout);
        return 0;
    }
    std::cout << "need status : LOGINED or CONNECTED" << std::endl;
    state->log(std::cout);
    return -1;
}

int BreakPointService::timeout(){
    std::cout << "BreakPointService::timeout "
        <<"-> query the data [" <<  breakPoint->get()+1 <<  ", MAX)" << std::endl;

    if(state->isLogined()){ 
        if(0 == sendMessage("breakPoint-req")){
            std::cout << "BreakPointService::saveToFile " << std::endl;
            breakPoint->set(breakPoint->get());
            return 0;
        }
        else{
            std::cout << "send message failed" << std::endl;
            return -1;
        }
    }
    else{
        std::cout << "need logined status:" << std::endl;
        state->log(std::cout);
        return -1;
    }
}

const BreakPointState & BreakPointService::getState() const{
    return *state;
}
